//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.IO;
using System.Text;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.XPath;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Services.Installer;
using DotNetNuke.Services.Installer.Packages;
using DotNetNuke.Services.Installer.Writers;
using DotNetNuke.Services.Localization;
using DotNetNuke.UI.Modules;
namespace DotNetNuke.Modules.Admin.Extensions
{
	partial class PackageWriter : ModuleUserControlBase
	{
		private PackageInfo _Package = null;
		private PackageWriterBase _Writer;
		public int PackageID
		{
			get
			{
				int _PageNo = 0;
				if (ViewState["PackageID"] != null)
				{
					_PageNo = Convert.ToInt32(ViewState["PackageID"]);
				}
				return _PageNo;
			}
			set { ViewState["PackageID"] = value; }
		}
		public PackageInfo Package
		{
			get
			{
				if (_Package == null && PackageID > Null.NullInteger)
				{
					_Package = PackageController.GetPackage(PackageID);
				}
				return _Package;
			}
		}
		public string ReturnURL
		{
			get
			{
				int TabID = ModuleContext.PortalSettings.HomeTabId;
				if (Request.Params["rtab"] != null)
				{
					TabID = int.Parse(Request.Params["rtab"]);
				}
				return Common.Globals.NavigateURL(TabID);
			}
		}
		private void CheckSecurity()
		{
			if (!ModuleContext.PortalSettings.UserInfo.IsSuperUser)
			{
				Response.Redirect(Common.Globals.NavigateURL("Access Denied"), true);
			}
		}
		private void CreateManifest()
		{
			foreach (string fileName in System.Text.RegularExpressions.Regex.Split(txtFiles.Text, Environment.NewLine))
			{
				string name = fileName.Trim();
				if (!string.IsNullOrEmpty(name))
				{
					InstallFile file = new InstallFile(name);
					_Writer.AddFile(file);
				}
			}
			foreach (string fileName in System.Text.RegularExpressions.Regex.Split(txtAssemblies.Text, Environment.NewLine))
			{
				string name = fileName.Trim();
				if (!string.IsNullOrEmpty(name))
				{
					InstallFile file = new InstallFile(name);
					_Writer.AddFile(file);
				}
			}
			txtManifest.Text = _Writer.WriteManifest(false);
		}
		private void CreatePackage()
		{
			CheckSecurity();
			string manifestName = txtManifestName.Text;
			if (string.IsNullOrEmpty(manifestName))
			{
				manifestName = txtArchiveName.Text.ToLower().Replace("zip", "dnn");
			}
			if (chkPackage.Checked)
			{
				Installer installer = new Installer(Package, Request.MapPath("."));
				foreach (InstallFile file in installer.InstallerInfo.Files.Values)
				{
					_Writer.AddFile(file);
				}
				string basePath;
				switch (Package.PackageType)
				{
					case "Auth_System":
						basePath = Common.Globals.InstallMapPath + ("AuthSystem");
						break;
					case "Container":
						basePath = Common.Globals.InstallMapPath + ("Container");
						break;
					case "CoreLanguagePack":
					case "ExtensionLanguagePack":
						basePath = Common.Globals.InstallMapPath + ("Language");
						break;
					case "Module":
						basePath = Common.Globals.InstallMapPath + ("Module");
						break;
					case "Provider":
						basePath = Common.Globals.InstallMapPath + ("Provider");
						break;
					case "Skin":
						basePath = Common.Globals.InstallMapPath + ("Skin");
						break;
					default:
						basePath = Common.Globals.HostMapPath;
						break;
				}
				if (!manifestName.EndsWith(".dnn"))
				{
					manifestName += ".dnn";
				}
				if (!txtArchiveName.Text.EndsWith(".zip"))
				{
					txtArchiveName.Text += ".zip";
				}
				_Writer.CreatePackage(Path.Combine(basePath, txtArchiveName.Text), manifestName, Package.Manifest, true);
				DotNetNuke.UI.Skins.Skin.AddModuleMessage(this, string.Format(Localization.GetString("Success", this.LocalResourceFile), this.ModuleContext.PortalSettings.PortalAlias.HTTPAlias + basePath.Replace(Common.Globals.ApplicationMapPath, "").Replace("\\", "/")), DotNetNuke.UI.Skins.Controls.ModuleMessage.ModuleMessageType.GreenSuccess);
			}
			else if (chkManifest.Checked)
			{
				_Writer.WriteManifest(manifestName, Package.Manifest);
			}
			phInstallLogs.Controls.Add(_Writer.Log.GetLogsTable());
		}
		private void GetAssemblies(bool refreshList)
		{
			GetFiles(string.IsNullOrEmpty(txtFiles.Text));
			if (refreshList)
			{
				txtAssemblies.Text = Null.NullString;
				foreach (InstallFile file in _Writer.Assemblies.Values)
				{
					txtAssemblies.Text += file.FullName + Environment.NewLine;
				}
			}
		}
		private void GetFiles(bool refreshList)
		{
			_Writer.GetFiles(chkIncludeSource.Checked);
			if (refreshList)
			{
				txtFiles.Text = Null.NullString;
				foreach (InstallFile file in _Writer.AppCodeFiles.Values)
				{
					txtFiles.Text += "[app_code]" + file.FullName + Environment.NewLine;
				}
				foreach (InstallFile file in _Writer.Scripts.Values)
				{
					txtFiles.Text += file.FullName + Environment.NewLine;
				}
				foreach (InstallFile file in _Writer.Files.Values)
				{
					txtFiles.Text += file.FullName + Environment.NewLine;
				}
			}
		}
		protected string GetText(string type)
		{
			string text = Null.NullString;
			if (type == "Title")
			{
				text = Localization.GetString(wizPackage.ActiveStep.Title + ".Title", this.LocalResourceFile);
			}
			else if (type == "Help")
			{
				text = Localization.GetString(wizPackage.ActiveStep.Title + ".Help", this.LocalResourceFile);
			}
			return text;
		}
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			if ((Request.QueryString["packageid"] != null))
			{
				PackageID = Int32.Parse(Request.QueryString["packageid"]);
			}
			else
			{
				PackageID = Null.NullInteger;
			}
		}
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			chkUseManifest.CheckedChanged += new EventHandler(chkUseManifest_CheckedChanged);
			cmdGetFiles.Click += new EventHandler(cmdGetFiles_Click);
			wizPackage.ActiveStepChanged += new EventHandler(wizPackage_ActiveStepChanged);
			wizPackage.CancelButtonClick += new EventHandler(wizPackage_CancelButtonClick);
			wizPackage.FinishButtonClick += new WizardNavigationEventHandler(wizPackage_FinishButtonClick);
			wizPackage.NextButtonClick += new WizardNavigationEventHandler(wizPackage_NextButtonClick);

			try
			{
				CheckSecurity();
				ctlPackage.EditMode = UI.WebControls.PropertyEditorMode.View;
				ctlPackage.DataSource = Package;
				ctlPackage.DataBind();
				wizPackage.CancelButtonText = "<img src=\"" + Common.Globals.ApplicationPath + "/images/lt.gif\" border=\"0\" /> " + Localization.GetString("Cancel", this.LocalResourceFile);
				wizPackage.StartNextButtonText = "<img src=\"" + Common.Globals.ApplicationPath + "/images/rt.gif\" border=\"0\" /> " + Localization.GetString("Next", this.LocalResourceFile);
				wizPackage.StepNextButtonText = "<img src=\"" + Common.Globals.ApplicationPath + "/images/rt.gif\" border=\"0\" /> " + Localization.GetString("Next", this.LocalResourceFile);
				wizPackage.StepPreviousButtonText = "<img src=\"" + Common.Globals.ApplicationPath + "/images/lt.gif\" border=\"0\" /> " + Localization.GetString("Previous", this.LocalResourceFile);
				wizPackage.FinishCompleteButtonText = "<img src=\"" + Common.Globals.ApplicationPath + "/images/lt.gif\" border=\"0\" /> " + Localization.GetString("Cancel", this.LocalResourceFile);
				_Writer = PackageWriterFactory.GetWriter(Package);
				if (Page.IsPostBack)
				{
					_Writer.BasePath = txtBasePath.Text;
				}
				else
				{
					txtBasePath.Text = _Writer.BasePath;
					if (!string.IsNullOrEmpty(Package.Manifest))
					{
						cboManifests.Items.Add(new ListItem("Database version", ""));
					}
					string filePath = Server.MapPath(_Writer.BasePath);
					if (!string.IsNullOrEmpty(filePath))
					{
						if (Directory.Exists(filePath))
						{
							foreach (string file in Directory.GetFiles(filePath, "*.dnn"))
							{
								string fileName = file.Replace(filePath + "\\", "");
								cboManifests.Items.Add(new ListItem(fileName, fileName));
							}
							foreach (string file in Directory.GetFiles(filePath, "*.dnn.resources"))
							{
								string fileName = file.Replace(filePath + "\\", "");
								cboManifests.Items.Add(new ListItem(fileName, fileName));
							}
						}
					}
					if (cboManifests.Items.Count > 0)
					{
						trUseManifest.Visible = true;
                    }
				}
			}
			catch (Exception exc)
			{
				Services.Exceptions.Exceptions.ProcessModuleLoadException(this, exc);
			}
		}
		protected void chkUseManifest_CheckedChanged(object sender, System.EventArgs e)
		{
			trManifestList.Visible = chkUseManifest.Checked;
		}
		protected void cmdGetFiles_Click(object sender, System.EventArgs e)
		{
			GetFiles(true);
		}
		protected void wizPackage_ActiveStepChanged(object sender, System.EventArgs e)
		{
			switch (wizPackage.ActiveStepIndex)
			{
				case 1:
					if (chkUseManifest.Checked)
					{
						wizPackage.ActiveStepIndex = 3;
					}
					GetFiles(string.IsNullOrEmpty(txtFiles.Text));
					chkIncludeSource.Visible = _Writer.HasProjectFile || _Writer.AppCodeFiles.Count > 0;
					break;
				case 2:
					if (_Writer.IncludeAssemblies)
					{
						GetAssemblies(string.IsNullOrEmpty(txtAssemblies.Text));
					}
					else
					{
						wizPackage.ActiveStepIndex = 3;
					}
					break;
				case 3:
					if (chkUseManifest.Checked)
					{
						if (string.IsNullOrEmpty(cboManifests.SelectedValue))
						{
							StringBuilder sb = new StringBuilder();
							XmlWriterSettings settings = new XmlWriterSettings();
							settings.ConformanceLevel = ConformanceLevel.Fragment;
							settings.OmitXmlDeclaration = true;
							settings.Indent = true;
							_Writer.WriteManifest(XmlWriter.Create(sb, settings), Package.Manifest);
							txtManifest.Text = sb.ToString();
						}
						else
						{
							string filename = Path.Combine(Server.MapPath(_Writer.BasePath), cboManifests.SelectedValue);
							StreamReader objStreamReader = File.OpenText(filename);
							txtManifest.Text = objStreamReader.ReadToEnd();
						}
					}
					else
					{
						CreateManifest();
					}
					if (!chkReviewManifest.Checked)
					{
						wizPackage.ActiveStepIndex = 4;
					}
					break;
				case 4:
					txtManifestName.Text = Package.Owner + "_" + Package.Name;
					if (chkUseManifest.Checked)
					{
						txtArchiveName.Text = Package.Owner + "_" + Package.Name + "_" + Common.Globals.FormatVersion(Package.Version) + "_Install.zip";
						chkManifest.Checked = true;
						trManifest1.Visible = false;
						trManifest2.Visible = false;
					}
					else
					{
						if (chkIncludeSource.Checked)
						{
							txtArchiveName.Text = Package.Owner + "_" + Package.Name + "_" + Common.Globals.FormatVersion(Package.Version) + "_Source.zip";
						}
						else
						{
							txtArchiveName.Text = Package.Owner + "_" + Package.Name + "_" + Common.Globals.FormatVersion(Package.Version) + "_Install.zip";
						}
					}
					if (!txtManifestName.Text.ToLower().EndsWith(".dnn"))
						txtManifestName.Text = txtManifestName.Text + ".dnn";
					wizPackage.DisplayCancelButton = false;
					break;
			}
		}
		protected void wizPackage_CancelButtonClick(object sender, System.EventArgs e)
		{
			try
			{
				Response.Redirect(ReturnURL, true);
			}
			catch (Exception exc)
			{
				Services.Exceptions.Exceptions.ProcessModuleLoadException(this, exc);
			}
		}
		protected void wizPackage_FinishButtonClick(object sender, System.Web.UI.WebControls.WizardNavigationEventArgs e)
		{
			try
			{
				Response.Redirect(ReturnURL, true);
			}
			catch (Exception exc)
			{
				Services.Exceptions.Exceptions.ProcessModuleLoadException(this, exc);
			}
		}
		protected void wizPackage_NextButtonClick(object sender, System.Web.UI.WebControls.WizardNavigationEventArgs e)
		{
			CheckSecurity();
			switch (e.CurrentStepIndex)
			{
				case 3:
					XPathDocument doc = new XPathDocument(new StringReader(txtManifest.Text));
					XPathNavigator nav = doc.CreateNavigator();
					XPathNavigator packageNav = nav.SelectSingleNode("dotnetnuke/packages");
					Package.Manifest = packageNav.InnerXml;
					PackageController.SavePackage(Package);
					break;
				case 4:
					if (chkManifest.Checked && (!string.IsNullOrEmpty(txtManifestName.Text)) && (!txtManifestName.Text.ToLower().EndsWith(".dnn")))
					{
						lblMessage.Text = Localization.GetString("InvalidManifestExtension", this.LocalResourceFile);
						e.Cancel = true;
					}
					else if (chkPackage.Checked && string.IsNullOrEmpty(txtArchiveName.Text))
					{
						lblMessage.Text = Localization.GetString("NoFileName", this.LocalResourceFile);
						e.Cancel = true;
					}
					else if (chkPackage.Checked && !txtArchiveName.Text.ToLower().EndsWith(".zip"))
					{
						lblMessage.Text = Localization.GetString("InvalidPackageName", this.LocalResourceFile);
						e.Cancel = true;
					}
					else
					{
						CreatePackage();
					}
					break;
			}
		}
	}
}
